/* Pattern walker UI
 *
 * Based upon:
 * - http://toc.oreilly.com/2011/11/html5-for-publishers-canvas.html
 * - Richard Garside - www.nogginbox.co.uk [2010]
 *
 * Copyright, 2012, KU Leuven
 */

// Setup event handlers
window.onload = init;
function init(e) {
  patternWalkerApp(e);
}

function patternWalkerApp(e) {

  var cb_canvas = null;
  var cb_ctx = null;
  var cb_lastPoints = null;
  var cb_easing = 0.4;

  var defaulthost = "http://localhost:5000/";

  var gridxsize   = 30;
  var gridysize   = 20;
  var gridxspacer = null;
  var gridyspacer = null;

  var resetButton = null;

  function canvasSupport() {
    return Modernizr.canvas;
  }

  if (!canvasSupport()) {
    return;
  }

  document.getElementById("host").value = defaulthost;
  resetButton  = document.getElementById("reset_image");
  resetButton.addEventListener('click', resetPressed, false);

  cb_canvas = document.getElementById("drawview");

  gridxspacer = Math.round(cb_canvas.width / gridxsize);
  gridyspacer = Math.round(cb_canvas.height / gridysize);

	cb_lastPoints = Array();

	if (cb_canvas.getContext) {
		cb_ctx = cb_canvas.getContext('2d');
		cb_ctx.lineWidth = 2;
		cb_ctx.strokeStyle = "rgb(0, 0, 0)";
		cb_ctx.beginPath();

		cb_canvas.onmousedown = startDraw;
		cb_canvas.onmouseup = stopDraw;
		cb_canvas.ontouchstart = startDraw;
		cb_canvas.ontouchstop = stopDraw;
		cb_canvas.ontouchmove = drawMouse;
	}

  drawGrid();

  function startDraw(e) {
    if (e.touches) {
      // Touch event
      for (var i = 1; i <= e.touches.length; i++) {
        cb_lastPoints[i] = getCoords(e.touches[i - 1]); // Get info for finger #1
      }
    }
    else {
      // Mouse event
      cb_lastPoints[0] = getCoords(e);
      cb_canvas.onmousemove = drawMouse;
    }

    return false;
  }

  // Called whenever cursor position changes after drawing has started
  function stopDraw(e) {
    e.preventDefault();
    cb_canvas.onmousemove = null;
    brighten();
  }

  function drawMouse(e) {
    if (e.touches) {
      // Touch Enabled
      for (var i = 1; i <= e.touches.length; i++) {
        var p = getCoords(e.touches[i - 1]); // Get info for finger i
        cb_lastPoints[i] = drawLine(cb_lastPoints[i].x, cb_lastPoints[i].y, p.x, p.y);
      }
    }
    else {
      // Not touch enabled
      var p = getCoords(e);
      cb_lastPoints[0] = drawLine(cb_lastPoints[0].x, cb_lastPoints[0].y, p.x, p.y);
    }

    return false;
  }

  // Draw a line on the canvas from (s)tart to (e)nd
  function drawLine(sX, sY, eX, eY) {
    cb_ctx.strokeStyle = '#ffffff'; 
    cb_ctx.beginPath();
    cb_ctx.moveTo(sX, sY);
    cb_ctx.lineTo(eX, eY);
    cb_ctx.stroke();
    cb_ctx.closePath();
    return { x: eX, y: eY };
  }

  function pressPlate(p) {
    var gp = gridPoint(p);
    cb_ctx.fillStyle="#000080";
    cb_ctx.fillRect(gp.x*gridxspacer+1, gp.y*gridyspacer+1, gridxspacer-2, gridyspacer-2);
    addPoint(gp);
  }

  // Get the coordinates for a mouse or touch event
  function getCoords(e) {
    var p = null;
    if (e.offsetX) {
      p = { x: e.offsetX, y: e.offsetY, t: Date.now() };
    }
    else if (e.layerX) {
      p = { x: e.layerX, y: e.layerY, t: Date.now() };
    }
    else {
      p = { x: e.pageX - cb_canvas.offsetLeft, y: e.pageY - cb_canvas.offsetTop, t: Date.now()};
    }
    pressPlate(p);
    return p;
  }

  function gridPoint(p) {
    var xg = Math.round(p.x/gridxspacer - 0.5);
    var yg = Math.round(p.y/gridyspacer - 0.5);
    //console.log('('+p.x+','+p.y+') -> ('+xg+','+yg+')');
    return {x: xg, y:yg, t:p.t};
  }

  function resetPressed(e) {
    //theCanvas.width = theCanvas.width; // Reset grid
    document.getElementById("sendview").getElementsByClassName("content").innerHTML = "";
    document.getElementById("receiveview").getElementsByClassName("content").innerHTML = "";
    resetGrid();
  }

  function resetGrid() {
    cb_ctx.fillStyle = 'white';
    cb_ctx.fillRect(0, 0, cb_canvas.width, cb_canvas.height);
    drawGrid();
  }

  function drawGrid() {
    cb_ctx.strokeStyle = '#6c6c6c';
    cb_ctx.strokeRect(1,  1, cb_canvas.width-2, cb_canvas.height-2);
    for (var x = 0; x < gridxsize*gridxspacer; x += gridxspacer) {
      cb_ctx.moveTo(x,0);
      cb_ctx.lineTo(x,cb_canvas.height);
      cb_ctx.stroke();
    }
    for (var y = 0; y < gridysize*gridyspacer; y += gridyspacer) {
      //console.log("Draw line (0,"+y+")--("+theCanvas.length+","+y+")");
      cb_ctx.moveTo(0,y);
      cb_ctx.lineTo(cb_canvas.width,y);
      cb_ctx.stroke();
    }
    //cb_ctx.strokeStyle = '#000000';
  }

  function brighten() {
    var adjustment = 50;
    var pixels = cb_ctx.getImageData(0,0,cb_canvas.width, cb_canvas.height);
    var d = pixels.data;
    for (var i=0; i<d.length; i+=4) {
      d[i] += adjustment;
      d[i+1] += adjustment;
      d[i+2] += adjustment;
    }
    cb_ctx.putImageData(pixels, 0, 0);
    drawGrid();
  }


  var sendToServerQueue = [];
  var sendtoServerTimer = -1;
  var server = "localhost"

  function sendPointsToServer() {
    console.log("Sending");

    clearTimeout(sendtoServerTimer);
    sendtoServerTimer = -1;

    // Clean points
    var newQueue = [];
    //var prevx = -1;
    //var prevy = -1;
    //sendToServerQueue.forEach(function(p) {
      //if (p.x != prevx && p.y != prevy) {
        //prevx = p.x;
        //prevy = p.y;
        //newQueue.push(p);
      //}
    //});
    // Don't clean points
    newQueue = sendToServerQueue;

    // Setup communication
    var jsondata = JSON.stringify({points: newQueue});
    var sendview = document.getElementById("sendview").getElementsByClassName("content")[0];
	var host = document.getElementById("host").value;
    sendview.innerHTML = sendview.innerHTML+"<br>"+Date()+"<br>"+jsondata+"<br> host="+host;
    

    jQuery.ajax({
      type: "POST",
      url: host,
      data: {json: jsondata},
      success: function(msg) {
        var receiveview = document.getElementById("receiveview").getElementsByClassName("content")[0];
        receiveview.innerHTML = receiveview.innerHTML+"<br>"+Date()+"<br>"+msg;
      },
    });
    sendToServerQueue = [];
  }

  function addPoint(p) {
    sendToServerQueue.push(p);
    if (sendtoServerTimer === -1) {
      // Send points to server every second after start of movement.
      sendtoServerTimer = setTimeout(sendPointsToServer, 1000);
    }
  }
}
